#include "mathx.h"

/*
Generates a random integer.
Inputs:
	-Min: Minimum number
	-Max: Maximum number
Returns:
	-Random number, obviously.
*/
int RandInt(int Min, int Max)
{
	int r;
	int mi, ma, adj = 0;
	if(Min < 0) adj = 0 - Min; //To handle negative ranges
	mi = Min + adj;
	ma = (Max + adj) - GREATEROF(Min, 0);
	r = (int)(((ma + 1) * rand() / (RAND_MAX + 1.0)) + mi) - adj;
	return r;
}


/*
Generates a random float.
Input:
	-Min: Minimum number
	-Max: Maximum number
Returns:
	-Come on, this should be easy.
*/
float RandFloat(float Min, float Max)
{
	float r;
	float mi, ma, adj=0;
	if(Min < 0) adj = 0 - Min; //To handle negative ranges
	mi = Min + adj;
	ma = (Max + adj) - GREATEROF(Min, 0);
	r = (((ma + 1) * rand() / (RAND_MAX + 1.0)) + mi) - adj;
	return r;
}


/*
Fills an array with unique random integers.
Input:
	-RandPtr: Pointer to int array to hold random numbers.
	-ArrSize: Size of array.
Notes:
	-Requires RandInt().
	-The integers used are incrementing values placed in random order. For
	 example, if the array has 16 elements, it will contain the numbers 0 to 15
	 in random order.
	-Can take a while with large arrays.
*/
void UniqueRand(int* RandPtr, int ArrSize)
{
	int count = 0, rn;
	for(count=0;count<ArrSize;count++)
		RandPtr[count] = - 1; //Fill with an unused value
	count = 0;

	while(count < ArrSize)
	{
		rn = RandInt(0,ArrSize - 1); //Choose one of the array entries randomly
		if(RandPtr[rn] == -1) //If it hasn't been filled yet,
		{
			RandPtr[rn] = count; //Fill it with the counter value,
			count++; //and increment the counter.
		}
	} //Keep doing so until all elements are filled.
}


/*
Calculates an exponent.
Inputs:
	-Num: Number to multiply
	-Power: Exponent
Returns: Num to the Power exponent
Notes:
	-Probably won't work with negatives.
*/
int Exp(int Num, int Power)
{
	if(Power > 0)
	{
		int i, n;
		n = Num;
		for(i = 1; i < Power; i++)
			n *= Num;
		return n;
	}
	else
		return 1;
}


/*
Averages an array of integers.
Inputs:
	-Arr: Array to average.
	-Num: Number of elements in the array.
Returns: Average of elements.
Notes:
	-Won't work if the total of the elements exceeds the range of an integer.
*/
int Average(int* Arr, int Num)
{
	int i, Total = 0;

	for(i=0; i<Num; i++)
		Total += Arr[i];

	return Total / Num;
}


/*
Converts a bit flag to an index. (e.g 1 -> 0, 2 -> 1, 4 -> 2, 8 -> 3...)
Inputs:
	-Bit : Bit flag to convert.
Returns: Index.
Notes:
	-Todo: there's probably a better way to do this.
	-If multiple bits are set, the lowest is used.
*/
unsigned int BitToIndex(unsigned int Bit)
{
	int Index = 0;

	if(!Bit) return 0;
	while(!(Bit & 1))
	{
		Bit >>= 1;
		Index++;
	}
	return Index;
}


/*
Rounds up to the next power of two.
Inputs:
	-Num: Number to round.
Returns: Next power of two.
*/
unsigned int NextPowerOf2(unsigned int Num)
{
	unsigned int i;
	for(i=1; i<Num; i <<= 1);
	return i;
}
